<template>
  <el-dialog
    v-model="dialogVisible"
    :show-close="false"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    :modal="false"
    draggable
    :append-to-body="true"
    :fullscreen="isFullscreen"
    :class="{ 'video-call-modal': true }"
    modal-class="video-call-dialog-modal"
    :before-close="handleClose"
    :width="miniMode ? 240 : null"
  >
    <template #header>
      <div class="video-call-header">
        <div class="header-left"></div>
        <span class="dialog-title">{{ title }}</span>
        <div class="header-controls">
          <el-button link @click="setMiniMode()">
            <img :src="miniMode ? scale : minIcon" style="width: 16px" />
          </el-button>
          <el-button link @click="toggleFullscreen">
            <img :src="isFullscreen ? max : fullIcon" style="width: 16px" />
          </el-button>
          <el-button link @click="handleClose"
            ><el-icon color="#fff"><Close /></el-icon
          ></el-button>
        </div>
      </div>
    </template>
    <iframe
      ref="videoChatIframeRef"
      :src="props.videoURL"
      allow="microphone;camera;midi;encrypted-media;display-capture;"
      :style="{ width: '100%' }"
      @load="onIframeLoad"
    ></iframe>
  </el-dialog>
</template>

<script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from 'vue';
import max from '@/assets/images/max.png';
import scale from '@/assets/images/scale.png';
import { Close } from '@element-plus/icons-vue';
import minIcon from '@/assets/images/min.png';
import fullIcon from '@/assets/images/full.png';
import { ElMessage } from 'element-plus';

const props = defineProps<{
  videoURL: string;
}>();
const emit = defineEmits(['close']);
const miniMode = ref(false);
const dialogVisible = ref(false);
const isFullscreen = ref(false);
const title = ref('视频通话窗口');
const videoChatIframeRef = ref<any>(null);
const videoChatIframeWidth = ref(0);
let resizeWatchTimer: any = 0;

const showDialog = () => {
  console.log('显示视频通话窗口');
  dialogVisible.value = true;
  resizeWatch();
};

const handleClose = () => {
  dialogVisible.value = false;
  emit('close');
};

function setMiniMode() {
  miniMode.value = !miniMode.value;
  isFullscreen.value = false;
  iframeResize();
}

const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value;
  if (isFullscreen.value) {
    miniMode.value = false;
  }
  console.log(`iframe width ${videoChatIframeRef.value.offsetWidth}`);
};

const onIframeLoad = () => {
  console.log('视频控件加载完成');
  iframeResize();
};

/**
 * 监控视频窗口大小变化，变化时设置默认宽高比高度
 * resizeWatchTimer 等于-1时结束监控
 */
const resizeWatch = () => {
  if (resizeWatchTimer === -1) {
    return false;
  }
  resizeWatchTimer = setTimeout(() => {
    console.log('视频窗口大小变化监听');
    iframeResize();
    resizeWatch();
  }, 500);
};

const iframeResize = () => {
  const iframe = videoChatIframeRef.value;
  if (iframe) {
    if (videoChatIframeWidth.value !== iframe.offsetWidth || !iframe.height) {
      console.log('调整视频窗口尺寸');
      videoChatIframeWidth.value = iframe.offsetWidth;
      // 全屏高度- dialog header高度
      const viewportHeight = document.documentElement.clientHeight - 32;
      // 当成员窗口未打开时设置1020:611宽高比
      iframe.height = Math.min(viewportHeight, iframe.offsetWidth / (1020 / 611));
    }
  }
};

/**
 * 房间连接状态变更
 * @param state "connected" | "connecting" | "disconnected" | "reconnecting"
 */
const onConnectionStateChanged = (state: string) => {
  // 状态变更为断开状态时关闭窗口
  if (state === 'disconnected') {
    handleClose();
  }
};

/**
 * 开启/禁用媒体设备
 *
 * @param trackSource 1 摄像头 2 麦克风 3 屏幕共享
 * @param enable 是否禁用
 */
function openCameraMic(soucreType: number, isMute: boolean) {
  const action = soucreType === 1 ? 'setCameraEnabled' : 'setMicrophoneEnabled';
  sendCommand({ action, data: !isMute });
}

/**
 * 给iframe发控制消息
 * @param message 消息
 */
function sendCommand(message: any) {
  videoChatIframeRef.value.contentWindow.postMessage(message, '*');
}

onMounted(() => {
  // 监听视频窗口发来的消息
  window.addEventListener(
    'message',
    function (event) {
      console.log('Received message: ', event.data);
      const action = event.data.action;
      switch (action) {
        case 'connectionStateChanged':
          onConnectionStateChanged(event.data.data);
          break;
        case 'participantUpdate':
          participantUpdate(event.data.data);
          break;
        case 'onLeave':
          console.error('点击离开， 调用接口');
          break;
      }
    },
    false
  );
});
type ConnectionQuality = 'excellent' | 'good' | 'poor' | 'lost' | 'unknown';
/** Interface */
interface Participant {
  connectionQuality: ConnectionQuality;
  identity: string;
  name: string;
  isLocal: boolean;
  isCameraEnabled: boolean;
  isMicrophoneEnabled: boolean;
  joinedAt: Date | undefined;
  tracks: [];
}
const participants = ref([] as Participant[]);
// 更新成员信息
const participantUpdate = (eventData: Participant[]) => {
  connectTip(eventData);
};
const goodQuelities = ['excellent', 'good'];
const badQuelities = ['lost', 'poor'];
function connectTip(eventData: Participant[]) {
  eventData.forEach((item) => {
    const old = participants.value.find((oldItem) => oldItem.identity === item.identity);
    if (old) {
      const quality = item.connectionQuality;
      const oldQuality = old.connectionQuality;
      if (quality && oldQuality && oldQuality !== quality) {
        console.log(`=============================> ${item.name}`, oldQuality, quality);
        // 网络变好了，或者网络变坏了
        if (goodQuelities.includes(quality) && badQuelities.includes(oldQuality)) {
          ElMessage.success(`${item.name} 的网络已恢复`);
        } else if (badQuelities.includes(quality) && goodQuelities.includes(oldQuality)) {
          ElMessage.error(`${item.name} 的网络状况较差`);
        }
      }
    }
  });
}
onUnmounted(() => {
  window.removeEventListener('message', function () {});
});

watch(dialogVisible, (val) => {
  if (val) {
    // 设置定时任务不等于-1重新开始监控任务
    resizeWatchTimer = 0;
    resizeWatch();
  } else {
    // 设置-1停止监控窗口大小变化
    resizeWatchTimer = -1;
  }
});

defineExpose({
  showDialog,
  handleClose,
  openCameraMic
});
</script>

<style lang="scss">
.video-call-dialog-modal {
  pointer-events: none;
  .el-dialog {
    pointer-events: auto;
  }
}
.video-call-modal {
  background-color: rgba(0, 0, 0);
  overflow: hidden;
  padding: 0 !important;
  .el-dialog__header {
    padding: 0 !important;

    .video-call-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background-color: #2b2b33; /* 黑色背景 */
      color: #fff;
      border-bottom: 1px solid #ebeef5;

      .header-left > * {
        margin-left: 10px;
      }
      .dialog-title {
        flex: 1;
        text-align: center;
        font-size: 14px;
        font-weight: bold;
      }

      .header-controls > * {
        margin-left: 0;
        margin-right: 10px;
      }
    }
  }

  .el-dialog__body {
    padding: 0 !important;

    iframe {
      border: 1px solid #2b72fe;

      .lk-grid-layout {
        padding: 0 !important;
      }
    }
  }
}
</style>
